package com.zzyl.nursing.service.member.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzyl.common.utils.DateUtils;
import com.zzyl.common.utils.StringUtils;
import com.zzyl.common.utils.bean.BeanUtils;
import com.zzyl.framework.interceptor.ThreadLocalUser;
import com.zzyl.nursing.domain.Reservation;
import com.zzyl.nursing.dto.memberDto.ReservationDto;
import com.zzyl.nursing.dto.memberDto.ReservationPageDto;
import com.zzyl.nursing.mapper.member.IMemberReservationMapper;
import com.zzyl.nursing.service.member.IMemberReservationService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;

@Service
@Slf4j
@RequiredArgsConstructor
@Transactional(rollbackFor = Exception.class)
public class MemberReservationServiceImpl extends ServiceImpl<IMemberReservationMapper, Reservation> implements IMemberReservationService {

    private final IMemberReservationMapper memberReservationMapper;
    //预约状态，0：待报道，1：已完成，2：取消，3：过期 给我写四个常量
    public static final int STATUS_WAITING = 0;
    public static final int STATUS_COMPLETED = 1;
    public static final int STATUS_CANCELED = 2;
    public static final int STATUS_EXPIRED = 3;
    /**
     * 保存预约信息
     * @param reservationDto
     */
    @Override
    public void saveReservation(ReservationDto reservationDto) {
        Integer cancelCount = cancelledCount();
        if (cancelCount >= 3) {
            new RuntimeException("今日预约次数用尽，请明日重新预约");
        }
        Reservation reservation = new Reservation();
        BeanUtils.copyBeanProp(reservation, reservationDto);
        System.out.println("setUser thread: " + Thread.currentThread().getId());
        Long userId = ThreadLocalUser.getUser();
        reservation.setTime(DateUtils.parseDate(reservationDto.getTime()));
        reservation.setCreateBy(userId);
        reservation.setCreateTime(DateUtils.getNowDate());
        reservation.setStatus(STATUS_WAITING);
        super.save(reservation);
    }

    /**
     * 分页查询预约信息
     * @param reservationPageDto
     * @return
     */
    @Override
    public IPage<Reservation> pageReservation(ReservationPageDto reservationPageDto) {
        Page<Reservation> page = new Page<>(reservationPageDto.getPageNum(), reservationPageDto.getPageSize());
       //查询全部 就是status为null
        if(reservationPageDto.getStatus() == null) {
            QueryWrapper<Reservation> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq(reservationPageDto.getStatus() != null, "status", reservationPageDto.getStatus());
            return memberReservationMapper.selectPage(page, queryWrapper);
        }
        //否则就是查询预约信息
        IPage<Reservation> result = memberReservationMapper.selectPage(page,
                Wrappers.<Reservation>lambdaQuery().eq(Reservation::getStatus, reservationPageDto.getStatus()));
        return result;
    }

    /**
     * 取消预约
     * @param id
     */
    @Override
    public void cancelReservation(Long id) {
        // 通过id查询预约信息
        Reservation reservation = memberReservationMapper.selectById(id);

        if (reservation == null || !reservation.getStatus().equals(STATUS_WAITING)) {
            log.info("预约信息不存在");
            throw new RuntimeException("预约信息不存在");
        }

        reservation.setStatus(STATUS_CANCELED);
        // 直接根据id更新
        memberReservationMapper.updateById(reservation);

        log.info("取消预约成功");
    }

    /**
     * 查询取消预约数量
     * @return
     */
    @Override
    public Integer cancelledCount() {
        //时间在当天  定义限制时间传过去好让sql写
        Long userId = ThreadLocalUser.getUser();
        LocalDate today = LocalDate.now();
        LocalDateTime startOfDay = today.atStartOfDay();
        LocalDateTime endOfDay = today.atTime(23, 59, 59);
        Integer count = memberReservationMapper.cancelledCount(userId, startOfDay, endOfDay);
        return count;
    }

}
